package com.alibaba.citrus.ots.sales.plan.repository;

import com.alibaba.citrus.ots.common.annotation.RepositoryInvoker;
import com.alibaba.citrus.ots.common.util.CalculatePercentage;
import com.alibaba.citrus.ots.sales.plan.converter.PlanCustomerConverter;
import com.alibaba.citrus.ots.sales.plan.converter.PlanScItemConverter;
import com.alibaba.citrus.ots.sales.plan.converter.SalesPlanLineConverter;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.PageQueryPlanLineRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QuerySalesPlanLineRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanBatchQueryRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanDetailBatchQueryRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanSubTotalRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.response.SalesPlanSubTotalResponse;
import com.alibaba.citrus.ots.sales.plan.model.SalesPlanLineStatusEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.ContractDifferenceMoneyStampEnum;
import com.alibaba.citrus.ots.sales.plan.model.features.SalesPlanLineFeatures;
import com.alibaba.citrus.ots.sales.plan.repository.request.StatCustomerQueryRequest;
import com.alibaba.citrus.ots.sales.plan.repository.request.StatScItemQueryRequest;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanLineSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanStatCustomerSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanStatScItemSDO;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.sales_plan.salesplandetail.dto.*;
import com.epoch.app.bcots.sales_plan.salesplandetail.model.SalesPlanDetail;
import com.epoch.app.bcots.sales_plan.salesplandetail.service.SalesPlanDetailService;
import net.sf.json.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wangyibing
 */
@Component
public class SalesPlanLineRepositoryImpl implements SalesPlanLineRepository {

    private static final Log log = Log.getLogger(SalesPlanLineRepositoryImpl.class);


    @Resource
    private SalesPlanDetailService salesPlanDetailService;

    @Override
    @RepositoryInvoker(printLog = true)
    public String save(SalesPlanLineSDO salesPlanLineSDO) {
//            fillInContractCountAndMoney(salesPlanLineSDO);
        SalesPlanDetail salesPlanDetail = new SalesPlanDetail();
        BeanUtils.copyProperties(salesPlanLineSDO, salesPlanDetail);
        String features = JSON.toJSONString(salesPlanLineSDO.getSalesPlanLineFeatures());
        salesPlanDetail.setFeatures(features);
        CreateSalesPlanDetailResponse detailResponse = salesPlanDetailService.createSalesPlanDetail(salesPlanDetail);
        return detailResponse.getLastInsertId();
    }


    @Override
    @RepositoryInvoker(printLog = true)
    public SalesPlanLineSDO querySalesPlanLine(QuerySalesPlanLineRequest querySalesPlanLineRequest) {
        LoadSalesPlanDetailRequest loadSalesPlanDetailRequest = new LoadSalesPlanDetailRequest();
        BeanUtils.copyProperties(querySalesPlanLineRequest, loadSalesPlanDetailRequest);
        SalesPlanDetail salesPlanDetail = salesPlanDetailService.loadSalesPlanDetail(loadSalesPlanDetailRequest);
        return SalesPlanLineConverter.planLineDoToSdo(salesPlanDetail);
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public Integer edit(SalesPlanLineSDO salesPlanLineSDO) {
        SalesPlanDetail salesPlanDetail = new SalesPlanDetail();
        BeanUtils.copyProperties(salesPlanLineSDO, salesPlanDetail);
        salesPlanDetail.setGmtModified(new Date());
        UpdateSalesPlanDetailResponse response = salesPlanDetailService.updateSalesPlanDetail(salesPlanDetail);
        return response.getCount();
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public Integer delete(SalesPlanLineSDO salesPlanLineSDO) {
        /*DeleteSalesPlanDetailRequest deleteSalesPlanDetailRequest = new DeleteSalesPlanDetailRequest();
        deleteSalesPlanDetailRequest.setId(String.valueOf(salesPlanLineSDO.getId()));
        LoadSalesPlanDetailRequest id = LoadSalesPlanDetailRequest.newBuilder().id(String.valueOf(salesPlanLineSDO.getId())).build();
        SalesPlanDetail salesPlanDetail = salesPlanDetailService.loadSalesPlanDetail(id);
        salesPlanDetail.setStatus(-1);
        UpdateSalesPlanDetailResponse updateSalesPlanDetailResponse = salesPlanDetailService.updateSalesPlanDetail(salesPlanDetail);
        return updateSalesPlanDetailResponse.getCount();*/
        return 0;
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public String batchCreateSalesPlanLine(List<SalesPlanLineSDO> salesPlanLineSDOList) {
        BatchCreateSalesPlanDetailRequest salesPlanDetailRequest = BatchCreateSalesPlanDetailRequest.builder().salesPlanDetails(salesPlanLineSDOList).build();
        BatchCreateSalesPlanDetailResponse batchCreateSalesPlanDetailResponse = salesPlanDetailService.batchCreateSalesPlanDetail(salesPlanDetailRequest);
        return batchCreateSalesPlanDetailResponse.getSuccess();
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public PageResult<List<SalesPlanLineSDO>> pageQuerySalesPlanLineList(PageQueryPlanLineRequest pageQuerySalePlanRequest) {
        LoadSalesPlanDetailListRequest salesPlanDetailLoadListRequest = new LoadSalesPlanDetailListRequest();
        BeanUtils.copyProperties(pageQuerySalePlanRequest, salesPlanDetailLoadListRequest);
        if (ContractDifferenceMoneyStampEnum.SATISFY.getStamp().equals(pageQuerySalePlanRequest.getContractDifferenceMoneyStamp())) {
            salesPlanDetailLoadListRequest.setGtSatisfy(0);
        } else if (ContractDifferenceMoneyStampEnum.DISSATISFY.getStamp().equals(pageQuerySalePlanRequest.getContractDifferenceMoneyStamp())) {
            salesPlanDetailLoadListRequest.setLtSatisfy(0);
        }
        Result<List<SalesPlanDetail>> listResult = salesPlanDetailService.loadSalesPlanDetailList(salesPlanDetailLoadListRequest);
        List<SalesPlanLineSDO> collect = listResult.getResult().stream().map(salesPlanDetail -> {
            SalesPlanLineSDO salesPlanLineSDO = SalesPlanLineSDO.builder().build();
            BeanUtils.copyProperties(salesPlanDetail, salesPlanLineSDO);
            return salesPlanLineSDO;
        }).collect(Collectors.toList());
        return PageResult.of(collect, listResult.getTotal());
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public SalesPlanSubTotalResponse subTotalSalesPlanLine(SalesPlanSubTotalRequest salesPlanSubTotalRequest) {
        SubTotalSalesPlanLineRequest subTotalSalesPlanLineRequest = SubTotalSalesPlanLineRequest.builder().build();
        BeanUtils.copyProperties(salesPlanSubTotalRequest, subTotalSalesPlanLineRequest);
        if (ContractDifferenceMoneyStampEnum.SATISFY.getStamp().equals(salesPlanSubTotalRequest.getContractDifferenceMoneyStamp())) {
            subTotalSalesPlanLineRequest.setGtSatisfy(0);
        } else if (ContractDifferenceMoneyStampEnum.DISSATISFY.getStamp().equals(salesPlanSubTotalRequest.getContractDifferenceMoneyStamp())) {
            subTotalSalesPlanLineRequest.setLtSatisfy(0);
        }
        SubTotalSalesPlanLineResponse subTotalSalesPlanLineResponse = salesPlanDetailService.subTotalSalesPlanLine(subTotalSalesPlanLineRequest);
        SalesPlanSubTotalResponse salesPlanSubTotalResponse = SalesPlanSubTotalResponse.builder().build();
        BeanUtils.copyProperties(subTotalSalesPlanLineResponse, salesPlanSubTotalResponse);
        return salesPlanSubTotalResponse;
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public BigDecimal queryCompletePercent(SalesPlanSubTotalRequest salesPlanSubTotalRequest) {
        QueryCompletePercentRequest queryCompletePercentRequest = new QueryCompletePercentRequest();
        BeanUtils.copyProperties(salesPlanSubTotalRequest, queryCompletePercentRequest);
        //全部
        QueryCompletePercentResponse allPercentResponse = salesPlanDetailService.queryCompletePercent(queryCompletePercentRequest);
        if (allPercentResponse != null && allPercentResponse.getCount() != 0) {
            //未完成
            List<Integer> statusList = new ArrayList();
            statusList.add(SalesPlanLineStatusEnum.DRAFT.getStatus());
            queryCompletePercentRequest.setStatusList(statusList);
            QueryCompletePercentResponse toBeLockedPercentResponse = salesPlanDetailService.queryCompletePercent(queryCompletePercentRequest);
            Long toBeLockedCount = toBeLockedPercentResponse.getCount() != null ? toBeLockedPercentResponse.getCount() : 0L;
            return CalculatePercentage.retainTwo(allPercentResponse.getCount() - toBeLockedCount, allPercentResponse.getCount());
        }
        return new BigDecimal("0");
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public List<String> querySalesPlanLineByCustomerAddress(SalesPlanSubTotalRequest salesPlanSubTotalRequest) {
        QueryCustomerAddressSalesPlanDetailRequest queryCustomerAddressSalesPlanDetailRequest = new QueryCustomerAddressSalesPlanDetailRequest();
        BeanUtils.copyProperties(salesPlanSubTotalRequest, queryCustomerAddressSalesPlanDetailRequest);
        return salesPlanDetailService.queryCustomerAddressSalesPlanDetail(queryCustomerAddressSalesPlanDetailRequest).getResult();
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public List<SalesPlanLineSDO> batchQueryDetailByIds(SalesPlanDetailBatchQueryRequest salesPlanDetailBatchQueryRequest) {
        BatchQueryDetailByIdsRequest batchQueryDetailByIdsRequest = BatchQueryDetailByIdsRequest.builder().build();
        if (null != salesPlanDetailBatchQueryRequest.getIds()) {
            batchQueryDetailByIdsRequest.setIds(salesPlanDetailBatchQueryRequest.getIds());
        }
        if (null != salesPlanDetailBatchQueryRequest.getPlanIds()) {
            batchQueryDetailByIdsRequest.setPlanIds(salesPlanDetailBatchQueryRequest.getPlanIds());
        }
        if (null != salesPlanDetailBatchQueryRequest.getCustomerAddress()) {
            batchQueryDetailByIdsRequest.setCustomerAddress(salesPlanDetailBatchQueryRequest.getCustomerAddress());
        }
        if (null != salesPlanDetailBatchQueryRequest.getScItemIds()) {
            batchQueryDetailByIdsRequest.setScItemIds(salesPlanDetailBatchQueryRequest.getScItemIds());
        }
        if (CollectionUtils.isNotEmpty(salesPlanDetailBatchQueryRequest.getCustomerAddressIds())){
            batchQueryDetailByIdsRequest.setCustomerAddressIds(salesPlanDetailBatchQueryRequest.getCustomerAddressIds());
        }
        BatchQueryDetailByIdsResponse batchQueryDetailByIdsResponse = salesPlanDetailService.batchQueryDetailByIds(batchQueryDetailByIdsRequest);
        List<SalesPlanLineSDO> salesPlanLineSDOS = batchQueryDetailByIdsResponse.getResult().stream().map(salesPlanDetail -> {
            SalesPlanLineSDO salesPlanLineSDO = SalesPlanLineSDO.builder().build();
            BeanUtils.copyProperties(salesPlanDetail, salesPlanLineSDO);
            try {
                SalesPlanLineFeatures salesPlanLineFeatures = (SalesPlanLineFeatures) JSONObject.toBean(JSONObject.fromObject(salesPlanLineSDO.getFeatures()), SalesPlanLineFeatures.class);
                salesPlanLineSDO.setSalesPlanLineFeatures(salesPlanLineFeatures);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return salesPlanLineSDO;
        }).collect(Collectors.toList());
        return salesPlanLineSDOS;
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public List<SalesPlanLineSDO> batchQueryDetail(SalesPlanBatchQueryRequest salesPlanBatchQueryRequest) {
        BatchQueryDetailRequest batchQueryDetailRequest = BatchQueryDetailRequest.builder()
                .planId(salesPlanBatchQueryRequest.getPlanId())
                .orgBusinessUnitCode(salesPlanBatchQueryRequest.getOrgBusinessUnitCode())
                .orgSalesOrganizationCode(salesPlanBatchQueryRequest.getOrgSalesOrganizationCode())
                .orgSalesChannelCode(salesPlanBatchQueryRequest.getOrgSalesChannelCode())
                .orgSalesDepartmentCode(salesPlanBatchQueryRequest.getOrgSalesDepartmentCode())
                .ids(salesPlanBatchQueryRequest.getIds())
                .scItemId(salesPlanBatchQueryRequest.getScItemId())
                .build();
        Result<List<SalesPlanDetail>> batchQueryDetail = salesPlanDetailService.batchQueryDetail(batchQueryDetailRequest);
        List<SalesPlanLineSDO> salesPlanLineSDOList = batchQueryDetail.getResult().stream().map(salesPlanDetail -> {
            SalesPlanLineSDO salesPlanLineSDO = SalesPlanLineSDO.builder().build();
            BeanUtils.copyProperties(salesPlanDetail, salesPlanLineSDO);
            return salesPlanLineSDO;
        }).collect(Collectors.toList());
        return salesPlanLineSDOList;
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public List<String> querySalesPlanLineByScItem(SalesPlanSubTotalRequest salesPlanSubTotalRequest) {
        QueryScItemSalesPlanDetailRequest queryScItemSalesPlanDetailRequest = new QueryScItemSalesPlanDetailRequest();
        BeanUtils.copyProperties(salesPlanSubTotalRequest, queryScItemSalesPlanDetailRequest);
        return salesPlanDetailService.queryScItemSalesPlanDetail(queryScItemSalesPlanDetailRequest).getResult();
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public PageResult<List<SalesPlanLineSDO>> pageQuerySalesPlanLineAdjustAddList(PageQueryPlanLineRequest pageQuerySalePlanRequest) {
        LoadSalesPlanDetailAdjustAddListRequest salesPlanDetailAdjustAddListRequest = new LoadSalesPlanDetailAdjustAddListRequest();
        BeanUtils.copyProperties(pageQuerySalePlanRequest, salesPlanDetailAdjustAddListRequest);
        if (ContractDifferenceMoneyStampEnum.SATISFY.getStamp().equals(pageQuerySalePlanRequest.getContractDifferenceMoneyStamp())) {
            salesPlanDetailAdjustAddListRequest.setGtSatisfy(0);
        } else if (ContractDifferenceMoneyStampEnum.DISSATISFY.getStamp().equals(pageQuerySalePlanRequest.getContractDifferenceMoneyStamp())) {
            salesPlanDetailAdjustAddListRequest.setLtSatisfy(0);
        }
        Result<List<SalesPlanDetail>> listResult = salesPlanDetailService.loadSalesPlanDetailAdjustAddList(salesPlanDetailAdjustAddListRequest);
        List<SalesPlanLineSDO> collect = listResult.getResult().stream().map(salesPlanDetail -> {
            SalesPlanLineSDO salesPlanLineSDO = SalesPlanLineSDO.builder().build();
            BeanUtils.copyProperties(salesPlanDetail, salesPlanLineSDO);
            return salesPlanLineSDO;
        }).collect(Collectors.toList());
        return PageResult.of(collect, listResult.getTotal());
    }

    @Override
    public Integer batchUpdateById(List<SalesPlanLineSDO> request) {
        if (CollectionUtils.isEmpty(request)){
            return 0;
        }
        BatchUpdateSalesPlanDetailRequest detailRequest = new BatchUpdateSalesPlanDetailRequest();
        detailRequest.setSalesPlanDetails(SalesPlanLineConverter.planLineSdoToDoList(request));
        BatchUpdateSalesPlanDetailResponse batchUpdateSalesPlanDetailResponse = salesPlanDetailService.batchUpdateSalesPlanDetail(detailRequest);
        if (batchUpdateSalesPlanDetailResponse == null){
            log.error("SalesPlanLineRepositoryImpl.batchUpdateById failed");
            return 0;
        }
        if (batchUpdateSalesPlanDetailResponse.getError() != null && batchUpdateSalesPlanDetailResponse.getError() > 0){
            log.error("SalesPlanLineRepositoryImpl.batchUpdateById result:"+batchUpdateSalesPlanDetailResponse);
        }
        return batchUpdateSalesPlanDetailResponse.getSuccess();
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public Integer queryPlanCustomerCount(String planId,List<Integer> statusList) {
        PlanCustomerStatCountRequest request = new PlanCustomerStatCountRequest();
        request.setPlanId(planId);
        request.setStatusList(statusList);
        PlanCustomerStatCountResponse planCustomerStatCountResponse = salesPlanDetailService.planCustomerStatCount(request);
        if (planCustomerStatCountResponse != null) {
            return planCustomerStatCountResponse.getCount();
        }
        return null;
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public Integer batchUpdateLineStatus(List<SalesPlanLineSDO> salesPlanLineSDOList) {
        List<Long> ids = salesPlanLineSDOList.stream().map(SalesPlanLineSDO::getId).collect(Collectors.toList());
        BatchUpdateDetailStatusRequest batchUpdateDetailStatusRequest = BatchUpdateDetailStatusRequest.builder().ids(ids)
                .status(SalesPlanLineStatusEnum.DELETE.getStatus()).build();
        BatchUpdateDetailStatusResponse batchUpdateDetailStatusResponse = salesPlanDetailService.batchUpdateDetailStatus(batchUpdateDetailStatusRequest);
        return batchUpdateDetailStatusResponse.getCount();
    }


    @Override
    @RepositoryInvoker(printLog = true)
    public List<SalesPlanStatCustomerSDO> queryStatPlanCustomerList(StatCustomerQueryRequest statQueryRequest) {
        PlanCustomerStatRequest request = new PlanCustomerStatRequest();
        request.setPlanId(statQueryRequest.getPlanId());
        request.setStart(statQueryRequest.getStart());
        request.setLimit(statQueryRequest.getLimit());
        request.setStatusList(statQueryRequest.getStatusList());
        PlanCustomerStatResponse planCustomerStatResponse = salesPlanDetailService.planCustomerStat(request);
        if (planCustomerStatResponse != null) {
            return PlanCustomerConverter.planCustomerDoToSdo(planCustomerStatResponse.getResult());
        }
        return null;
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public List<SalesPlanStatScItemSDO> queryStatPlanScItemList(StatScItemQueryRequest statQueryRequest) {
        PlanScItemStatBySalesManRequest request = new PlanScItemStatBySalesManRequest();
        request.setPlanId(statQueryRequest.getPlanId());
        request.setManageEmployee(statQueryRequest.isManageEmployee());
        request.setOrgSalesDepartment(statQueryRequest.isOrgSalesDepartment());
        request.setOrgSalesChannel(statQueryRequest.isOrgSalesChannel());
        request.setOrgSalesOrganization(statQueryRequest.isOrgSalesOrganization());
        request.setOrgBusinessUnit(statQueryRequest.isOrgBusinessUnit());
        request.setStart(statQueryRequest.getStart());
        request.setLimit(statQueryRequest.getLimit());
        PlanScItemStatBySalesManResponse planScItemStatBySalesManResponse = salesPlanDetailService.planScItemStatBySalesMan(request);
        if (planScItemStatBySalesManResponse != null) {
            return PlanScItemConverter.planScItemDoToSdo(planScItemStatBySalesManResponse.getResult());
        }
        return null;
    }
}
